<?php

class Application_Model_User
{
    /**
     * @param int $limit
     * @return UserPOJO[]
     */
    public static function getLastLoggedInUsers($limit = 5)
    {
        $dbAdapter = JDbAdapter::factory();

        $userPOJOs = array();
        $assoc = $dbAdapter->fetchAll(
            $dbAdapter->select()
                ->from('USERS')
                ->order('LastLogout DESC')
                ->limit($limit)
        );
        foreach ($assoc as $row) {
            $userPOJO = new UserPOJO($row);
            array_push($userPOJOs, $userPOJO);
        }

        return $userPOJOs;
    }

    /**
     * @param int $id
     * @return UserPOJO
     */
    public static function getUser($id)
    {
        $dbAdapter = JDbAdapter::factory();

        $row = $dbAdapter->fetchRow(
            $dbAdapter->select()
                ->from('USERS')
                ->where('ID = ?', $id)
        );

        if ($row == null) {
            return null;
        }

        return new UserPOJO($row);
    }

    /**
     * @param string $username
     * @return int
     */
    public static function getUserID($username)
    {
        $dbAdapter = JDbAdapter::factory();

        $id = $dbAdapter->fetchOne(
            $dbAdapter->select('ID')
                ->from('USERS')
                ->where('Username = ?', $username)
        );

        return (int)$id;
    }

    /**
     * @param string $username
     * @param string $email
     * @param string $password
     * @param string $realName
     * @param string|Zend_Date $birthday
     * @param int $mobilePhone
     * @param int $userTypeID
     * @return int
     */
    public static function addUser($username, $email, $password, $realName,
                                   $birthday, $mobilePhone, $userTypeID = 2)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            if ($birthday instanceof Zend_Date) {
                $birthday = $birthday->get('y-M-d');
            }

            $dbAdapter->insert(
                'USERS',
                array(
                    'Username' => $username,
                    'Email' => $email,
                    'Password' => $password,
                    'RealName' => $realName,
                    'Birthday' => $birthday,
                    'MobilePhone' => $mobilePhone,
                    'UserTypeID' => $userTypeID
                )
            );

            return (int)$dbAdapter->lastInsertId('USERS');
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return 0;
        }
    }

    /**
     * @param string $id
     * @param string $password
     * @param string $realName
     * @param string|Zend_Date $birthday
     * @param int $mobilePhone
     * @param int $userTypeID
     * @return bool
     */
    public static function updateUser($id, $password, $realName, $birthday,
                                      $mobilePhone, $userTypeID)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            if ($birthday instanceof Zend_Date) {
                $birthday = $birthday->get('y-M-d');
            }

            $numberOfAffects = $dbAdapter->update(
                'USERS',
                array(
                    'Password' => $password,
                    'RealName' => $realName,
                    'Birthday' => $birthday,
                    'MobilePhone' => $mobilePhone,
                    'UserTypeID' => $userTypeID
                ),
                "ID = $id"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int[] $ids
     * @return bool
     */
    public static function deleteUsers($ids)
    {
        $dbAdapter = JDbAdapter::factory();

        $assoc = $dbAdapter->fetchAll(
            $dbAdapter->select()
                ->from('USERS')
                ->where('ID IN (?)', $ids)
        );
        foreach ($assoc as $row) {
            unset($row['ID']);
            $dbAdapter->insert('DELETED_USERS', $row);
        }

        try {
            $str = '(';
            $length = count($ids);
            for ($i = 0; $i < $length - 1; $i++) {
                $str .= $ids[$i] . ', ';
            }
            $str .= $ids[$length - 1];
            $str .= ')';
            $numberOfAffects = $dbAdapter->delete(
                'USERS', "ID IN $str"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int $id
     * @param string|Zend_Date $lastLogout
     * @return bool
     */
    public static function updateLastLogout($id, $lastLogout)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            if ($lastLogout instanceof Zend_Date) {
                $lastLogout = $lastLogout->get('y-M-d H:m:s');
            }

            $numberOfAffects = $dbAdapter->update(
                'USERS', array('LastLogout' => $lastLogout), "ID = $id"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int[] $ids
     * @return bool
     */
    public static function confirmUsers($ids)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            $str = '(';
            $length = count($ids);
            for ($i = 0; $i < $length - 1; $i++) {
                $str .= $ids[$i] . ', ';
            }
            $str .= $ids[$length - 1];
            $str .= ')';
            $numberOfAffects = $dbAdapter->update(
                'USERS', array('Confirmed' => true), "ID in $str"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int $id
     * @return bool
     */
    public static function confirmUser($id)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            $numberOfAffects = $dbAdapter->update(
                'USERS', array('Confirmed' => true), "ID = $id"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int $id
     * @return bool
     */
    public static function unconfirmUser($id)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            $numberOfAffects = $dbAdapter->update(
                'USERS', array('Confirmed' => false), "ID = $id"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int[] $ids
     * @return bool
     */
    public static function unblockUsers($ids)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            $str = '(';
            $length = count($ids);
            for ($i = 0; $i < $length - 1; $i++) {
                $str .= $ids[$i] . ', ';
            }
            $str .= $ids[$length - 1];
            $str .= ')';
            $numberOfAffects = $dbAdapter->update(
                'USERS', array('Enabled' => true), "ID in $str"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }

    /**
     * @param int[] $ids
     * @return bool
     */
    public static function blockUsers($ids)
    {
        $dbAdapter = JDbAdapter::factory();

        try {
            $str = '(';
            $length = count($ids);
            for ($i = 0; $i < $length - 1; $i++) {
                $str .= $ids[$i] . ', ';
            }
            $str .= $ids[$length - 1];
            $str .= ')';
            $numberOfAffects = $dbAdapter->update(
                'USERS', array('Enabled' => false), "ID in $str"
            );
            if ($numberOfAffects == 0) {
                return false;
            }

            return true;
        } catch (Exception $ex) {
            JLog::log($ex->getMessage());
            return false;
        }
    }
}

class UserPOJO extends POJO
{
    /** @var int */
    public $ID;

    /** @var string */
    public $Username;

    /** @var string */
    public $Password;

    /** @var string */
    public $Email;

    /** @var string */
    public $RealName;

    /** @var Zend_Date */
    public $Birthday;

    /** @var int */
    public $MobilePhone;

    /** @var string */
    public $LastLogout;

    /** @var Zend_Date */
    public $CreatedDate;

    /** @var bool */
    public $Confirmed;

    /** @var int */
    public $Enabled;

    /** @var int */
    public $UserTypeID;

    /**
     * @return void
     */
    protected function convert()
    {
        $this->ID = (int)$this->ID;
        $this->Username = (string)$this->Username;
        $this->Password = (string)$this->Password;
        $this->Email = (string)$this->Email;
        $this->RealName = (string)$this->RealName;
        $this->Birthday = new Zend_Date($this->Birthday);
        $this->MobilePhone = (int)$this->MobilePhone;
        $this->LastLogout = new Zend_Date($this->LastLogout);
        $this->CreatedDate = new Zend_Date($this->CreatedDate);
        $this->Confirmed = (bool)$this->Confirmed;
        $this->Enabled = (int)$this->Enabled;
        $this->UserTypeID = (int)$this->UserTypeID;
    }
}
